﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Threading;
using System.Diagnostics;

namespace SimpleLibrary
{
    class DataManager
    {
        private DataTable _allBooks;
        private DataTable _allusers;
        private static DataManager _instance;

        public static DataManager Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new DataManager();
                return _instance;
            }
            private set
            {
                _instance = value;
            }
        }

        private DataManager()
        {
            DbDriver.Instance.Init();
            _allusers = new DataTable();
            _allBooks = new DataTable();
            
        }

        public void Init()
        {
            //running as seperate thread for responsiveness.
            new Thread(LoadData).Start();
        }

        //Load the data from database
        private void LoadData()
        {
            try
            {
                Int64 userCount = 0;
                Int64 bookCount = 0;
                _allusers = DbDriver.Instance.Getusers(ref userCount);
                _allBooks = DbDriver.Instance.GetBooks(ref bookCount);

                Logger.WriteTrace("Loaded Books and Users Successfully. Users Count: " + userCount + " Books Count: " + bookCount,TraceLevel.Info);
            }
            catch (Exception exception)
            {
               Logger.WriteError("Error in Loading Data",exception.ToString());
            }
        }

        //used by Main screen to get the books from the local datatable using LINQ
        internal DataView GetAllBooks()
        {
            try
            {
                if (_allBooks.Rows.Count == 0)
                {
                    return new DataView();
                }
                EnumerableRowCollection<DataRow> query = from order in _allBooks.AsEnumerable()
                                                         orderby order.Field<Int32>("ID") ascending
                                                         select order;

                return query.AsDataView();
            }
            catch (Exception exception)
            {
                Logger.WriteError("Books::Error in Getting Books View.", exception.ToString());
            }
            return null;
        }

        //used by Main screen to get the users from the local datatable using LINQ
        internal DataView GetAllUsers()
        {
            try
            {
                if (_allusers.Rows.Count == 0)
                {
                    return new DataView();
                }
                EnumerableRowCollection<DataRow> query = from order in _allusers.AsEnumerable()
                                                         orderby order.Field<Int32>("ID") ascending
                                                         select order;

                return query.AsDataView();
            }
            catch (Exception exception)
            {
                Logger.WriteError("Books::Error in Getting Users View.", exception.ToString());
            }
            return null;
        }

        //used to get the Name of the user from the ID for showing the meaningful name.
        internal String GetNameFromId(String id)
        {
            try
            {
                if (_allusers.Rows.Count == 0)
                {
                    return String.Empty;
                }
                foreach (DataRow row in _allusers.Rows)
                {
                    if(row["ID"].ToString().Equals(id))
                    {
                        return row["strName"].ToString();
                    }
                }
            }
            catch (Exception exception)
            {
                Logger.WriteError("Books::Error in Getting Users View.", exception.ToString());
            }
            return String.Empty;
        }

        //getting the ID from the name for database operations.
        internal string GetIdFromName(string name)
        {
            try
            {
                if (_allusers.Rows.Count == 0)
                {
                    return String.Empty;
                }
                foreach (DataRow row in _allusers.Rows)
                {
                    if (row["strName"].ToString().Equals(name))
                    {
                        return row["ID"].ToString();
                    }
                }
            }
            catch (Exception exception)
            {
                Logger.WriteError("Books::Error in Getting Users View.", exception.ToString());
            }
            return String.Empty;
        }
    }
}
